#include "user.h"
#define SELF_TASK_ID TASK_ID_USER
#define TASK_SIGNAL_NUM	(8)
#define UART_BUF_SIZE (512)

typedef struct
{
	Timer_t RxTimer;
	Loop_Buffer Buffer;
	uint8_t Data[UART_BUF_SIZE * 2];
	uint8_t TxBuf[UART_BUF_SIZE];
	uint8_t RxBuf[LORA_DATA_MAX];
	uint8_t RxPos;
}USER_CtrlStruct;

static USER_CtrlStruct UserCtrl;
static Signal_InfoStruct SignalBuf[TASK_SIGNAL_NUM];

static void LoRaUser_UartTimerCB(PV_Union pData)
{
	Timer_Switch(&UserCtrl.RxTimer, 0);
	DBG_INFO("get data %dbyte", UserCtrl.RxPos);
	LoRaNode_Tx(UserCtrl.RxBuf, UserCtrl.RxPos);
	UserCtrl.RxPos = 0;
}

static void LoRaUser_UartCB(PV_Union pData)
{
	uint8_t RxData;
	Signal_InfoStruct Signal;
	switch (pData.u32)
	{
	case UART_RX_IRQ:
		UserCtrl.RxBuf[UserCtrl.RxPos] = Uart_Rx(COM_UART_ID);
		UserCtrl.RxPos++;
		if (UserCtrl.RxPos >= LORA_DATA_MAX)
		{
			DBG_INFO("get data %dbyte", UserCtrl.RxPos);
			LoRaNode_Tx(UserCtrl.RxBuf, UserCtrl.RxPos);
			UserCtrl.RxPos = 0;
		}
		Timer_Restart(&UserCtrl.RxTimer, 0, 5);
		break;
	case UART_TX_DONE_IRQ:
	case UART_TX_ERROR_IRQ:
		Task_SendOnlySignal(SELF_TASK_ID, SELF_TASK_ID, SIGNAL_UART_TX_DONE);
		break;
	}
}

static void LoRaUser_Timeout(Signal_InfoStruct *Signal)
{
	Task_Wait(SELF_TASK_ID, SIGNAL_ANY, 0);
}

static void LoRaUser_UartTxDone(Signal_InfoStruct *Signal)
{
	uint16_t TxLen;
	if (!Uart_CheckBusy(COM_UART_ID) && UserCtrl.Buffer.Len)
	{
		TxLen = LoopBuffer_Read(&UserCtrl.Buffer, UserCtrl.TxBuf, UART_BUF_SIZE);
		DBG_INFO("%d", TxLen);
		Uart_Tx(COM_UART_ID, UserCtrl.TxBuf, TxLen, 1);
		Task_Wait(SELF_TASK_ID, SIGNAL_ANY, 0);
		return ;
	}
	else
	{
		Task_Wait(SELF_TASK_ID, SIGNAL_ANY, 0);
		return ;
	}
}

static const Signal_AnalyzeStruct SignalAnalyze[] =
{
		{SIGNAL_TASK_TIMEOUT, LoRaUser_Timeout},
		{SIGNAL_UART_TX_REQ, LoRaUser_UartTxDone},
		{SIGNAL_UART_TX_DONE, LoRaUser_UartTxDone},
};
void LoRaUser_Task(Signal_InfoStruct *Signal)
{
	int i;
	if (!Signal)
	{
		Task_Wait(SELF_TASK_ID, SIGNAL_ANY, 0);
		return ;
	}
	for(i = 0; i < sizeof(SignalAnalyze)/sizeof(Signal_AnalyzeStruct);i++)
	{
		if (Signal->Signal == SignalAnalyze[i].Signal)
		{
			SignalAnalyze[i].Fun(Signal);
			return ;
		}
	}
	Task_Wait(SELF_TASK_ID, SIGNAL_ANY, 0);
}

void LoRaUser_TaskInit(void)
{
	Task_Register(SELF_TASK_ID, LoRaUser_Task, SignalBuf, TASK_SIGNAL_NUM);
	LoopBuffer_Init(&UserCtrl.Buffer, UserCtrl.Data, sizeof(UserCtrl.Data), 1);
#ifdef __LORA_NODE__
	Uart_Init(COM_UART_ID, COM_UART_BR, LoRaUser_UartCB);
	Uart_EnableRx(COM_UART_ID);
#endif

#ifdef __LORA_S_GATEWAY__
	Uart_Init(COM_UART_ID, COM_UART_BR, LoRaUser_UartCB);
#endif
	Timer_Register(&UserCtrl.RxTimer, LoRaUser_UartTimerCB, NULL);
	Task_Wait(SELF_TASK_ID, SIGNAL_ANY, 0);

}

void LoRaUser_PutRemoteRxData(uint8_t *Data, uint16_t Len)
{
	LoopBuffer_Write(&UserCtrl.Buffer, Data, Len);
	Task_SendOnlySignal(SELF_TASK_ID, SELF_TASK_ID, SIGNAL_UART_TX_REQ);
}

